package com.ophiux.pay.util;

import lombok.SneakyThrows;
import okhttp3.HttpUrl;
import org.springframework.util.Base64Utils;

import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.Signature;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @desc:
 * @author: hhl
 * @date：2023/9/1 13:56
 */
public class SignUtil {


    /**
     * 获取HTTP头
     * @param sign
     * @return
     */
    public String getAuthorization(String sign){
        String schema = "Authorization: WECHATPAY2-SHA256-RSA2048 "+sign;
        return schema;
    }

    /**
     * V3  SHA256withRSA 签名.
     *
     * @param method       请求方法  GET  POST PUT DELETE 等
     * @param canonicalUrl 例如  https://api.mch.weixin.qq.com/v3/pay/transactions/app?version=1 ——> /v3/pay/transactions/app?version=1
     * @param timestamp    当前时间戳   因为要配置到TOKEN 中所以 签名中的要跟TOKEN 保持一致
     * @param nonceStr     随机字符串  要和TOKEN中的保持一致
     * @param body         请求体 GET 为 "" POST 为JSON
     * @param keyPair      商户API 证书解析的密钥对  实际使用的是其中的私钥
     * @return the string
     */
    @SneakyThrows
    String sign(String method, String canonicalUrl, long timestamp, String nonceStr, String body, KeyPair keyPair) {
        String signatureStr = Stream.of(method, canonicalUrl, String.valueOf(timestamp), nonceStr, body).collect(Collectors.joining("\n", "", "\n"));
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(keyPair.getPrivate());
        sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
        return Base64Utils.encodeToString(sign.sign());
    }

    /**
     * 生成Token.
     *
     * @param mchId     商户号
     * @param nonceStr  随机字符串
     * @param timestamp 时间戳
     * @param serialNo  证书序列号
     * @param signature 签名
     * @return the string
     */
    String token(String mchId, String nonceStr, long timestamp, String serialNo, String signature) {
        final String TOKEN_PATTERN = "mchid=\"%s\",nonce_str=\"%s\",timestamp=\"%d\",serial_no=\"%s\",signature=\"%s\"";
        // 生成token
        return String.format(TOKEN_PATTERN, mchId, nonceStr, timestamp, serialNo, signature);
    }

}
